#ifndef PROCESS_MGMT_H
#define PROCESS_MGMT_H

#include <string>
#include "common.h"


class processes {
public:
    static processes &instance() { static processes pinstance; return pinstance; }
    static const enum console_mode{ PROC_CONSOLE_UNDEF, PROC_CONSOLE_DISABLED, PROC_CONSOLE_NEW, PROC_CONSOLE_CURRENT, };
    static const enum priority_set{ PROC_PRIORITY_UNDEF, PROC_PRIORITY_LOW, PROC_PRIORITY_NORMAL, PROC_PRIORITY_HIGH,  };

    static UINT_PTR process_create(std::string processNameRaw, std::string processPathRaw, std::string processParamsRaw, console_mode console,
                                   priority_set priority, UINT_PTR hStdInputRaw, UINT_PTR hStdOutputRaw, UINT_PTR hStdErrorRaw);
    static FunctionSuccesFailure process_wait(UINT_PTR hProcessRaw, UINT miliseconds);
    static FunctionSuccesFailure process_wait_infinite(UINT_PTR hProcessRaw);
    static FunctionSuccesFailure process_destroy(UINT_PTR hProcessRaw);

    static UINT_PTR thread_create(DWORD WINAPI proc(LPVOID), LPVOID param, SIZE_T stackSize);
    static UINT_PTR thread_get_current();
    static FunctionSuccesFailure thread_wait(UINT_PTR hThreadRaw, UINT miliseconds);
    static FunctionSuccesFailure thread_wait_infinite(UINT_PTR hThreadRaw);
    static FunctionSuccesFailure thread_ready();

    static UINT_PTR event_create(BOOL bManualReset, const std::string &eventNameRaw);
    static FunctionSuccesFailure event_signal(UINT_PTR hEventRaw);
    static FunctionSuccesFailure event_pulse(UINT_PTR hEventRaw);
    static FunctionSuccesFailure event_reset(UINT_PTR hEventRaw);
    static FunctionSuccesFailure event_wait(UINT_PTR hEventRaw, UINT miliseconds);
    static FunctionSuccesFailure event_wait_infinite(UINT_PTR hEventRaw);
    static FunctionSuccesFailure event_destroy(UINT_PTR hEventRaw);

    static UINT_PTR mutex_create(const std::string &mutexNameRaw);
    static FunctionSuccesFailure mutex_take(UINT_PTR hMutexRaw, UINT miliseconds);
    static FunctionSuccesFailure mutex_take_infinite(UINT_PTR hMutexRaw);
    static FunctionSuccesFailure mutex_release(UINT_PTR hMutexRaw);
    static FunctionSuccesFailure mutex_destroy(UINT_PTR hMutexRaw);

    static FunctionSuccesFailure pipe_unnamed_create(UINT_PTR &hReadPipeRaw, UINT_PTR &hWritePipeRaw);
    static FunctionSuccesFailure pipe_unnamed_read(UINT_PTR hReadPipeRaw, std::string &inBuffer);
    static FunctionSuccesFailure pipe_unnamed_write(UINT_PTR hWritePipeRaw, const std::string &outBuffer);
    static FunctionSuccesFailure pipe_unnamed_destroy(UINT_PTR hReadPipeRaw, UINT_PTR hWritePipeRaw);
    static FunctionSuccesFailure pipe_named_peek_data(UINT_PTR hReadPipeRaw, std::string &peekBuffer);

    static UINT_PTR pipe_named_create(BOOL bMessageType, BOOL bAsyncMode, UINT bufferSize, const std::string &namedPipeNameRaw);
    static UINT_PTR pipe_named_open(BOOL bAsyncMode, std::string &namedPipeNameRaw);
    static FunctionSuccesFailure pipe_named_client_wait(UINT_PTR hNamedPipeRaw);
    static FunctionSuccesFailure pipe_named_wait(std::string &namedPipeNameRaw, UINT miliseconds);
    static FunctionSuccesFailure pipe_named_wait_infinite(std::string &namedPipeNameRaw);
    static BOOL pipe_named_operation_is_pending(UINT_PTR hNamedPipeRaw);
    static FunctionSuccesFailure pipe_named_read(UINT_PTR hNamedPipeRaw, std::string &inBuffer);
    static FunctionSuccesFailure pipe_named_write(UINT_PTR hNamedPipeRaw, const std::string &outBuffer);
    static FunctionSuccesFailure pipe_named_destroy(UINT_PTR hNamedPipeRaw);

private:
    processes() {}
    processes(const processes&);
    processes &operator=(const processes&);
};


#endif
